package com.klangner.go.model.impl;

import java.util.Iterator;

import com.klangner.go.model.IBoard;
import com.klangner.go.model.IRuleChecker;
import com.klangner.go.model.IStonesGroup;
import com.klangner.go.model.Move;
import com.klangner.go.model.utils.BoardUtils;

public class AtariGoRules implements IRuleChecker {

	/**
	 * @see IRuleChecker#isLegalMove(Move)
	 */
	@Override
	public boolean isLegalMove(IBoard board, Move move) {

		Iterator<IStonesGroup> it;
		
		
    // In atari go pass is not accepted
    if (move.isPass()) {
    	return false;
    }

    // Check coordinates
    if( move.getX() < 0 || move.getX() >= board.getSize() || 
    		move.getY() < 0 || move.getY() >= board.getSize())
    {
    	return false;
    }

    // Can't put on another stone
    if (board.getStone(move.getX(), move.getY()) != IBoard.NO_STONE)
    	return false;

    // if move has at least one free liberty, it's legal
    if( BoardUtils.hasLiberty(board, move.getX(), move.getY()) )
    	return true;
    
    // Add stone to the board and check groups
    board.setStone(move.getX(), move.getY(), move.getColor());
    
    // find opposite group without liberties
    // If found then move is ok
    if(move.getColor() == IBoard.BLACK_STONE)
    	it = board.getGroups(IBoard.WHITE_STONE).iterator();
    else
    	it = board.getGroups(IBoard.BLACK_STONE).iterator();
    
    while( it.hasNext() ){
    	IStonesGroup group = it.next();
    	if(group.getLiberties().isEmpty()){
    		return true;
    	}
    }
    
    // check if this move is suicide
    it = board.getGroups(move.getColor()).iterator();
    while( it.hasNext() ){
    	IStonesGroup group = it.next();
    	if(group.getLiberties().isEmpty()){
    		return false;
    	}
    }
    
    return true;
	}

}
